package com.cjw.service.impl.database;

import com.cjw.mapper.database.ResourceMapper;
import com.cjw.pojo.dto.database.PageDTO;
import com.cjw.pojo.dto.database.ResourceDTO;
import com.cjw.pojo.entity.database.Resource;
import com.cjw.pojo.query.database.AddResourceDTO;
import com.cjw.pojo.query.database.ResourceQuery;
import com.cjw.pojo.query.database.UpdateResourceDTO;
import com.cjw.service.database.ResourceService;
import com.cjw.util.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service("resourceService")
public class ResourceServiceImpl implements ResourceService {
    @Autowired
    private ResourceMapper resourceMapper;

    @Override
    public List<ResourceDTO> queryByUserId(Long userId) {
        return treeResource(resourceMapper.queryByUserId(userId)).stream()
                .filter(resourceDTO -> resourceDTO.getParentId() == null)
                .collect(Collectors.toList());
    }

    @Override
    public List<ResourceDTO> queryByRoleId(Long roleId) {
        return treeResource(resourceMapper.queryByRoleId(roleId)).stream()
                .filter(resourceDTO -> resourceDTO.getParentId() == null)
                .collect(Collectors.toList());
    }

    @Override
    public PageDTO<List<Resource>> getList(ResourceQuery resourceQuery) {
        PageDTO<List<Resource>> resourceDTOPageDTO = new PageDTO<>();
        resourceQuery.setPage((resourceQuery.getPage()-1)*resourceQuery.getSize());
        resourceDTOPageDTO.setDtos(resourceMapper.queryByPage(resourceQuery));
        resourceDTOPageDTO.setTotal(resourceMapper.queryCount(resourceQuery));
        return resourceDTOPageDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(AddResourceDTO addResourceDTO) {
        Resource resource = new Resource();
        resource.setIcon(addResourceDTO.getIcon());
        resource.setName(addResourceDTO.getName());
        resource.setParentId(addResourceDTO.getParentId());
        resource.setUrl(addResourceDTO.getUrl());
        resource.setSrc(addResourceDTO.getSrc());
        resource.setType(1);//1-启用
        resource.setAddTime(new Date());
        resource.setUpdateTime(new Date());
        return resourceMapper.insertSelective(resource) == 1;
    }

    @Override
    public UpdateResourceDTO detail(Long id) {
        Resource resource = resourceMapper.selectByPrimaryKey(id);
        UpdateResourceDTO updateResourceDTO = new UpdateResourceDTO();
        updateResourceDTO.setIcon(resource.getIcon());
        updateResourceDTO.setId(resource.getId());
        updateResourceDTO.setName(resource.getName());
        updateResourceDTO.setParentId(resource.getParentId());
        updateResourceDTO.setSrc(resource.getSrc());
        updateResourceDTO.setUrl(resource.getUrl());
        return updateResourceDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(UpdateResourceDTO updateResourceDTO) {
        Resource resource = new Resource();
        resource.setSrc(updateResourceDTO.getSrc());
        resource.setUrl(updateResourceDTO.getUrl());
        resource.setParentId(updateResourceDTO.getParentId());
        resource.setName(updateResourceDTO.getName());
        resource.setIcon(updateResourceDTO.getIcon());
        resource.setUpdateTime(new Date());
        resource.setId(updateResourceDTO.getId());
        return resourceMapper.updateByPrimaryKeySelective(resource) == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(Long id) {
        Resource resource = new Resource();
        resource.setId(id);
        resource.setType(0);
        return resourceMapper.updateByPrimaryKeySelective(resource) == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean changeState(Long id) {
        Resource resource = new Resource();
        resource.setId(id);
        int type;
        if (resourceMapper.selectByPrimaryKey(id).getType() == 1)
            type = 0;
        else
            type = 1;
        resource.setType(type);
        return resourceMapper.updateByPrimaryKeySelective(resource)== 1;
    }

    /**
     * 将资源列表树型化
     * @param resources
     */
    private List<ResourceDTO> treeResource(List<Resource> resources) {
        List<ResourceDTO> resourceDTOList = new ArrayList<>();
        Map<Long, ResourceDTO> map = new HashMap<>();
        for (Resource resource : resources) {
            ResourceDTO resourceDTO = BeanUtils.copy(resource, ResourceDTO.class);
            map.put(resource.getId(), resourceDTO);
            resourceDTOList.add(resourceDTO);
        }
        for (ResourceDTO resourceDTO : resourceDTOList) {
            if (resourceDTO.getParentId() != null) {
                ResourceDTO parent = map.get(resourceDTO.getParentId());
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(resourceDTO);
            }
        }
        return resourceDTOList;
    }
}
